const { sqlite, database } = require("../JDBC");
const { ipcMain } = require("electron");
const windows = require("../../config/windows");

const fs = require("fs");
const Path = require("path");
const zlib = require("zlib");
const Bitwise = require('../BitwiseBuffer'); //按位运算库
const pngBase = require('./pngBase');

const { println } = require("../Console");
const { Console } = require("console");
const { fileIsExist } = require("../Common")
const { Task } = require("../Task");
// const println = console.log;

/**
 * NPK和IMG的处理工具
 * 1 为其他模块提供查询，并返回base64格式的图片
 * 2 索引、模糊查找、增删改查、转png
 */

/**
 * NPK文件结构：
 * [NPK_Header: [校验字节]+[img数量n]  ] +  [NPK_Index]*n =>[img数据包]*n
 *  
 * img数据包结构
 * [nimgF_Header: [校验字节]+[png数量m] ] + [nimgF_index]*m =>[png数据包]*m
 * 
 */


//文件名解密 秘钥
const fileNameBuffer = Buffer.from([
    "puchikon@neople dungeon and fighter ",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNFDNFDNFDNFDNF",
    "DNFDNFDNFDNFDNFDNFDNF\x00",
].join(""));

//NPK文件头
class NPK_Header {
    /*string:*/flag = null;// 文件标识 "NeoplePack_Bill"  [16]
    /*int:*/count = 0;     // 包内文件的数目

    constructor(flag, count) {
        this.flag = flag;
        this.count = count;
    }
};

//NPK索引
class NPK_Index {
    /*int:*/offset = 0;  //uint32_t  文件的包内偏移量
    /*int:*/size = 0;    //unit32_t  文件的大小
    /*string:*/name = "";   //char[256] 文件名

    constructor(offset, size, name) {
        this.offset = offset;
        this.size = size;
        this.name = name;
    }
}

//IMG文件头
class Img_Header {
    /*string:*/flag = null; // 文件标石"Neople Img File" [16]
    /*int:*/size = 0;	// 索引表大小，以字节为单位
    /*int:*/unknown1 = 0;
    /*int:*/unknown2 = 0;
    /*int:*/count = 0;// 索引表数目

    /*int*/ offset = 0;   //在文件中的偏移位置，应该==npkIndex.offset
    /*string*/index_name = null;

    constructor(index_name, flag, size, count, offset) {
        this.index_name = index_name;
        this.flag = flag;
        this.size = size;
        this.count = count;
        this.offset = offset;
    }
};

//IMG索引
class Img_Index {
    /*int:*/dwType = 0;     //目前已知的类型有 0x0E=14(1555格式) 0x0F=15(4444格式) 0x10=16(8888格式) 0x11=17(引用型 dwCompress指向引用的index)
    /*int:*/dwCompress = 0; // 目前已知的类型有 0x06=6(zlib压缩) 0x05=5(未压缩)
    /*int:*/width = 0;        // 宽度
    /*int:*/height = 0;       // 高度
    /*int:*/size = 0;         // 压缩时size为压缩后大小，未压缩时size为转换成8888格式时占用的内存大小
    /*int:*/key_x = 0;        // X关键点，当前图片在整图中的X坐标
    /*int:*/key_y = 0;        // Y关键点，当前图片在整图中的Y坐标
    /*int:*/max_width = 0;    // 整图的宽度
    /*int:*/max_height = 0;   // 整图的高度，有此数据是为了对齐精灵

    /*boolean*/vaild = true; //是否校验成功
    /*string */index_name = null;
    /*int    */index = 0;
    /*int    */argb_offset = 0;    //argb在npk文件的偏移起始位置
    /*Buffer */argb = null;     //读取argb文件流(解压后)

    constructor(index_name, index) {
        this.index_name = index_name;
        this.index = index;
    }
};


//游标，当前读取文件的缓存
const current_cursor = {
    path: null,
    step: -1,
    npkHeader: null,  //count对应npkIndexs.length
    npkIndexs: [],

    imgHeaders: [], //count对应imgIndexs.length
    imgIndexs: [],
}

//按阶段读取
const LOAD_STEP = {
    "START": 0, //未开始阶段
    "IMG": 1, //读取img列表
    "ARGB": 2,//读取纹理
    "PNG": 3,//转换成png实体类
}

//int32字节码 转10进制
//注意有符号最大21亿  无符号42亿，且没有负数
const hexInt32ToNum = (buffer) => {
    return parseInt(buffer.readUInt32LE(0).toString(10))
}

//字节转latin1
//并去掉多余的 \x00
const hexToLatin1 = (buffer) => {
    return buffer.toString("latin1").replace(/\x00/g, "");
}

//分段读取
//@param filepath
//@param start:int 开始位 按字节数
//@param end:int   结束位 [start,end]闭区间
const readStream = (filepath, start, end) => new Promise((res, rej) => {
    let data = "";

    const readStream = fs.createReadStream(filepath, {
        start,
        end,
    })

    /**
     * encoding支持类型：
     * ascii     --7 位 ASCII
     * utf8
     * base64
     * binary (=latin1 )   一字节编码 8位
     * hex                  16进制 4位
     */
    readStream.setEncoding('hex'); //读取编码为16进制

    readStream.on('data', chunk => {
        data += chunk;
    })
    readStream.on('end', () => {
        res(Buffer.from(data, "hex"));
    })
    readStream.on('error', err => {
        rej(err);
    })
})

//解析一个NPK文件
//@param path NPK文件路径
//@param step 解析到哪个阶段 LOAD_STEP
//使用回调的方式每次执行一个step，用cursor存储全部中间数据
const openNpk = (cursor, step) => new Promise((res, rej) => {
    // console.log("openNpk","willstep:",step,"cursorstep",cursor.step);

    if (cursor.step > step) {
        console.log("openNpk 跳过全部任务")
        return res(cursor);
    }

    //校验文件头，读取NpkHeader和NpkIndex
    if (cursor.step == LOAD_STEP.START) {
        readStream(cursor.path, 0, 19).then(buffer => {
            //校验文件头
            let checkBuffer = Buffer.from("NeoplePack_Bill\x00"); //标准文件头
            let loadBuffer = buffer.slice(1 - 1, 16); //1-16字节

            if (loadBuffer.length < 16 || Buffer.compare(checkBuffer, loadBuffer) != 0) {
                return rej(`读取NPK失败,未通过NpkHeader文件校验:${cursor.path}`)
            }

            let count = parseInt(buffer.readUInt32LE(17 - 1).toString(10)); //17-20字节 4字节 uint32
            let npkHeader = new NPK_Header("NeoplePack_Bill", count);
            // console.log("解析了一个npkHeader", npkHeader);

            cursor.npkHeader = npkHeader; //游标

            //读取NpkIndex
            readStream(cursor.path, 20, 20 + 264 * npkHeader.count - 1).then(buffer => {

                if (buffer.length != 264 * npkHeader.count) {
                    console.error("", buffer.length, 264 * npkHeader.count)
                    return rej(`读取NPK失败,npkIndex校验失败:${path}`)
                }

                for (let i = 0; i < npkHeader.count; i++) {
                    let start = 264 * i;
                    let end = start + 264

                    let loadBuffer = buffer.slice(start, end);

                    let offsetBuffer = loadBuffer.slice(1 - 1, 4); //4字节 uint32
                    let sizeBuffer = loadBuffer.slice(5 - 1, 8);   //4字节 uint32
                    let nameBuffer = loadBuffer.slice(9 - 1, 264); //256字节 char[256]
                    nameBuffer = Bitwise.xor(nameBuffer, fileNameBuffer);  //异或秘钥 得到name明文

                    let npkIndex = new NPK_Index(
                        hexInt32ToNum(offsetBuffer), //offset
                        hexInt32ToNum(sizeBuffer),//size
                        hexToLatin1(nameBuffer) //name
                    )

                    cursor.npkIndexs[i] = npkIndex;//游标
                    // console.warn("解析了一个NPK_Index", npkIndex);
                }

                // console.warn("LOAD_STEP.START 任务完成")
                return res(cursor);
            }).catch(e => {
                console.error("读取NpkIndex错误")
                console.error(e);
                rej(`读取NPK失败,读取NpkIndex错误:${e.toString()},${path}`)
            })

        }).catch(e => {
            console.error("读取NpkHeader错误")
            console.error(e);
            rej(`读取NPK失败,读取NpkHeader错误:${e.toString()},${path}`)
        })
        return;
    }


    //读取imgIndex+imgIndex
    //共npkHeader.count组任务，每组1个imgHeader+多个imgIndex
    if (cursor.step == LOAD_STEP.IMG) {

        //定义一个任务对象（任务数量,完成时回调）
        let task = new Task(cursor.npkHeader.count, (result) => {
            next(result);
        })

        for (let i = 0; i < cursor.npkHeader.count; i++) {
            let npkIndex = cursor.npkIndexs[i];
            let start = npkIndex.offset;
            let end = start + (16 + 4 * 4) - 1;

            //读取imgHeader并校验
            readStream(cursor.path, start, end).then(buffer => {
                if (buffer.length != (end - start + 1)) {
                    console.error("读取img数据包错误!", buffer.length, npkIndex.size);
                    cursor.errors.push(`读取img数据包错误,跳过该数据包,${npkIndex.name}`);
                    cursor.imgHeaders[i] = false;
                    task.push(false);
                    return;
                }

                //nif格式
                let checkBuffer = Buffer.from("Neople Img File\x00"); //[16]
                let loadBuffer = buffer.slice(1 - 1, 16);//1-16字节  16字节 char[16]

                if (loadBuffer.length != 16 || Buffer.compare(loadBuffer, checkBuffer) != 0) {
                    console.error("解析img数据包失败!", loadBuffer.length, loadBuffer.toString(), checkBuffer.toString());
                    cursor.errors.push(`解析img数据包失败,跳过该数据包,${npkIndex.name}`);
                    cursor.imgHeaders[i] = false;
                    task.push(false);
                    return;
                }

                let imgHeader = new Img_Header(
                    npkIndex.name,              //index_name
                    "Neople Img File",          //flag
                    parseInt(buffer.readUInt32LE(17 - 1).toString(10)),  //size   17-20 4字节 
                    parseInt(buffer.readUInt32LE(29 - 1).toString(10)),  //count  29-32 4字节
                    start                       //offset
                )
                // console.log("解析了一个NImgF_Header", imgHeader);
                cursor.imgHeaders[i] = imgHeader;

                //循环读取imgIndexs
                readStream(cursor.path, end, end + imgHeader.size).then(buffer => {
                    if (buffer.length != imgHeader.size + 1) { //这里size要加1 不知道为什么
                        console.error("读取img数据包错误!", buffer.length, npkIndex.size);
                        cursor.errors.push(`读取img数据包错误,跳过该数据包,${npkIndex.name}`);
                        cursor.imgHeaders[i] = false;
                        task.push(false);
                        return;
                    }

                    // console.log("imgindexs buffer.length", buffer.length)

                    //可能有跳过字段，每个imgIndexs大小是不固定的
                    //用这个变量记录上次读取结束的位置
                    let offsetPoint = 1;
                    let imgIndexs = []; //记录下本次找到的imgIndex

                    for (let j = 0; j < imgHeader.count; j++) {
                        let imgIndex = new Img_Index(imgHeader.index_name, j);//index_name,index
                        try {

                            imgIndex.dwType = buffer.readUInt32LE(offsetPoint).toString(10);
                            offsetPoint += 4;

                            imgIndex.dwCompress = buffer.readUInt32LE(offsetPoint);
                            offsetPoint += 4;

                            // console.log("开始读取属性", imgIndex.index_name, imgIndex.index, imgIndex.dwType, imgIndex.dwCompress)

                            if (imgIndex.dwType == 17) {
                                // 引用型，只有dwType,dwCompress两个数据
                                //dwCompress指向引用index
                                // console.log("imgIndex.dwType == 17","imgIndex.dwCompress",imgIndex.dwCompress,
                                //     "imgPath",imgIndex.index_name,"index",imgIndex.index);
                                //跳过

                            } else {
                                imgIndex.width = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.width = parseInt(imgIndex.width);
                                offsetPoint += 4;

                                imgIndex.height = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.height = parseInt(imgIndex.height);
                                offsetPoint += 4;

                                imgIndex.size = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.size = parseInt(imgIndex.size);
                                offsetPoint += 4;

                                imgIndex.key_x = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.key_x = parseInt(imgIndex.key_x);
                                offsetPoint += 4;

                                imgIndex.key_y = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.key_y = parseInt(imgIndex.key_y);
                                offsetPoint += 4;

                                imgIndex.max_width = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.max_width = parseInt(imgIndex.max_width);
                                offsetPoint += 4;

                                imgIndex.max_height = buffer.readUInt32LE(offsetPoint).toString(10);
                                imgIndex.max_height = parseInt(imgIndex.max_height);
                                offsetPoint += 4;
                            }

                            imgIndexs.push(imgIndex);
                            // console.log("解析了一个 NImgF_Index", JSON.stringify(imgIndex));

                        } catch (e) {
                            console.error(`解析NImgF_Index错误,${imgHeader.index_name}[${j}],${JSON.stringify(imgIndex)}`)
                            console.error(e)
                        }

                    }//end for

                    //计算offset
                    //并添加到cursor.imgIndexs中
                    {
                        //文件中 img数据包的位置+ imgHeader[16+4x4] + imgHeader.size+1 是第一张图片开始的位置
                        let startOffset = npkIndex.offset + 32 + imgHeader.size;
                        let lastOffset = startOffset;
                        imgIndexs.forEach((imgIndex, j) => {
                            imgIndex.argb_offset = lastOffset;
                            lastOffset += imgIndex.size;
                            cursor.imgIndexs.push(imgIndex);

                            //@TEST 校验一下 最大不能超过文件大小
                            // {
                            //     let fileStat = fs.statSync(cursor.path);
                            //     let fileSize = fileStat.size;

                            //     if (imgIndex.argb_offset + imgIndex.size > fileSize) {
                            //         console.log("超过了文件大小", imgIndex.index_name, imgIndex.index)
                            //         console.log("imgIndex.argb_offset+imgIndex.size =", imgIndex.argb_offset + imgIndex.size)
                            //         console.log("fileSize=", fileSize);
                            //     }

                            // }

                        });
                    }//end calc offset

                    //将引用类型替换为引用对象
                    {
                        imgIndexs.filter(e => e.dwType == 17).forEach(imgIndex => {
                            if (imgIndex.dwCompress < imgIndexs.length) {
                                let refImgIndex = imgIndexs[imgIndex.dwCompress];

                                if (refImgIndex) {
                                    Object.keys(refImgIndex)
                                        .filter(key => key != "index") //别把index也复制了
                                        .forEach(key => {
                                            imgIndex[key] = refImgIndex[key];
                                        })
                                }
                            }
                        })
                    }

                    //提交任务
                    task.push(true);
                }).catch(e => {
                    console.error("读取imgIndex错误", npkIndex)
                    console.error(e);
                    cursor.errors.push(`读取imgIndex错误,${npkIndex.name},${e.toString()}`)
                    task.push(false);
                })
            }).catch(e => {
                console.error("读取imgHeader错误", npkIndex)
                console.error(e);
                cursor.errors.push(`读取imgHeader错误,${npkIndex.name},${e.toString()}`)
                task.push(false);
            })
        }

        const next = (result) => {
            if (result.length != cursor.npkHeader.count) {
                console.error("loadImgNext wating:", result.length, cursor.npkHeader.count)
                rej(`内部错误,task索引错误,请重新执行操作`);
                return;
            }

            //@TEST打印一下解析结果
            // {
            //     console.log("step.IMG结束, cursor.imgIndexs.length=", cursor.imgIndexs.length);
            //     console.log(cursor.errors);

            //     cursor.imgIndexs
            //         .sort((e1, e2) => {
            //             if (e1.index_name != e2.index_name) {
            //                 return e1.index_name.localeCompare(e2.index_name)
            //             }

            //             return e1.index - e2.index;
            //         })
            //         .forEach(ii => {
            //             console.log(JSON.stringify(ii))
            //             // console.log(ii);
            //         })

            // }
            console.warn("LOAD_STEP.IMG 任务完成")
            res(cursor);
        }
        return;
    }

    if (cursor.step == LOAD_STEP.ARGB) {
        let task = new Task(cursor.imgIndexs.length, result => {
            next(result);
        })

        let compilted = 0;

        cursor.imgIndexs.forEach(imgIndex => {

            //如果是引用类型 
            //重设为引用对象
            if (imgIndex.dwType == 17) {
                let refImgIndexs = cursor.imgIndexs.filter(e => {
                    return e.index_name == imgIndex.index_name && e.index == imgIndex.dwCompress;
                })

                if (refImgIndexs && refImgIndexs.length >= 1) {
                    let refImgIndex = refImgIndexs[0];

                    Object.keys(refImgIndex)
                        .filter(key => key != "index") //别把index也复制了
                        .forEach(key => {
                            imgIndex[key] = refImgIndex[key];
                        })

                } else {
                    imgIndex.vaild = false;
                    task.push(false);
                    console.error(`读取argb失败,未发现引用对象,${imgIndex.index_name}[${imgIndex.index}]`)
                    console.error(`imgIndex.dwType=${imgIndex.dwType},imgIndex.dwCompress=${imgIndex.dwCompress}`)
                    cursor.errors.push(`读取argb失败,未发现引用对象,${imgIndex.index_name}[${imgIndex.index}]`);
                    return;
                }
            }

            let start = imgIndex.argb_offset;
            let end = start + imgIndex.size - 1;

            readStream(cursor.path, start, end).then(buffer => {
                if (buffer.length != imgIndex.size) {
                    imgIndex.vaild = false;
                    task.push(false);
                    console.error(`读取argb失败,错误的数据大小,${imgIndex.index_name}[${imgIndex.index}]`)
                    console.error(`buffer.lengt=${buffer.length},imgIndex.size=${imgIndex.size + 1}`);
                    cursor.errors.push(`读取argb失败,${imgIndex.index_name}[${imgIndex.index}]`);
                    return;
                }

                // console.log("读取了一个argb,",`start=${start},end=${end},end-1=${end-1}`);
                // console.log("buffer.length=",buffer.length,"imgIndex.size=",imgIndex.size,"dwCompress=",imgIndex.dwCompress)

                if (imgIndex.dwCompress == 6) {
                    //压缩数据

                    zlib.inflate(buffer, (err, if_buffer) => {
                        if (err) {
                            console.error("解压错误", imgIndex);
                            console.error(err);
                            imgIndex.vaild = false;
                            cursor.errors.push(`读取argb失败,未能解压数据,"${imgIndex.index_name}[${imgIndex.index}]"`);
                            return task.push(false);//任务失败
                        }

                        // console.log("zlib:", "解压前大小:", imgIndex.argb.length, "解压后大小:", if_buffer.length);
                        imgIndex.argb = if_buffer;
                        imgIndex.dwCompress = 5; //设置成5  方便其他引用型判断

                        compilted++
                        return task.push(true); //任务完成
                    })
                } else if (imgIndex.dwCompress == 5) {
                    //未压缩
                    imgIndex.argb = buffer;

                    compilted++;
                    return task.push(true); //任务完成

                } else {
                    //其他
                    console.error("未识别的索引类型")
                    imgIndex.vaild = false;
                    errors.push(`读取argb失败,未识别的索引类型,"${imgIndex.index_name}[${index}]", dwCompress=${imgIndex.dwCompress}`);
                    return task.push(false); //任务完成
                }
            })

        })
        const next = (result) => {
            if (result.length != cursor.imgIndexs.length) {
                console.error("loadArgbNext wating:", result.length, cursor.npkHeader.count)
                rej(`内部错误,task索引错误,请重新执行操作`);
                return;
            }

            //@TEST打印一下解析结果
            // {
            //     console.log("step.ARGB结束", cursor.imgIndexs.length, compilted);
            //     console.log(cursor.errors);

            //     cursor.imgIndexs
            //         .filter(e=> e.vaild)
            //         .sort((e1, e2) => {
            //             if (e1.index_name != e2.index_name) {
            //                 return e1.index_name.localeCompare(e2.index_name)
            //             }

            //             return e1.index - e2.index;
            //         })
            //         .forEach(ii => {
            //             let obj = {
            //                 dwType:ii.dwType,
            //                 dwCompress:ii.dwCompress,
            //                 index_name: ii.index_name,
            //                 index: ii.index,
            //                 argb_length: ii.argb.length
            //             }

            //             console.log(JSON.stringify(obj));
            //         })
            // }
            console.warn("LOAD_STEP.ARGB 任务完成")
            res(cursor);
        }

        return;
    }

    if (cursor.step == LOAD_STEP.PNG) {
        let task = new Task(cursor.imgIndexs.length, result => {
            next(result);
        })

        cursor.imgIndexs.forEach(imgIndex => {
            if (imgIndex.vaild != true) {
                console.error(`读取png失败，未通过校验的imgIndex,跳过该任务，${imgIndex.index_name}[${imgIndex.index}]`);
                cursor.errors.push(`读取png失败，未通过校验的imgIndex,跳过该任务，${imgIndex.index_name}[${imgIndex.index}]`)
                return task.push(false);
            }

            pngBase.getPngFile(imgIndex, imgIndex.argb)
                .then(png => {
                    cursor.imgPngs.push({
                        path: imgIndex.index_name,
                        index: imgIndex.index,
                        png: png,
                    })

                    task.push(true);//提交任务
                })
                .catch(e => {
                    console.error("argb转png失败!", `${imgIndex.index_name}[${imgIndex.index}]`)
                    console.error(e)
                    cursor.errors.push(`argb转png失败,"${imgIndex.index_name}[${imgIndex.index}]",${e.toString}`);
                    imgIndex.vaild = false;
                    task.push(false);
                })
        });


        const next = (result) => {
            if (result.length != cursor.imgIndexs.length) {
                console.error("loadPngNext wating:", result.length, cursor.npkHeader.count)
                rej(`内部错误,task索引错误,请重新执行操作`);
                return;
            }

            //@TEST打印一下解析结果
            // {
            //     console.log("stepPNG结束", cursor.imgIndexs.length, cursor.imgPngs.length);
            //     console.log(cursor.errors);

            //     cursor.imgPngs
            //         .sort((e1, e2) => {
            //             if (e1.path != e2.path) {
            //                 return e1.path.localeCompare(e2.path)
            //             }

            //             return e1.index - e2.index;
            //         })
            //         .forEach(ip => {
            //             let obj = {
            //                 path: ip.path,
            //                 index: ip.index,
            //                 png: typeof (ip.png)
            //             }
            //             console.log(JSON.stringify(obj));
            //         })
            // }
            console.warn("LOAD_STEP.PNG任务完成")
            res(cursor);
        }
        return;
    }
});

/*代理方法 */
const openNpkProxy = (path, step) => {
    // console.log("openNpkProxy");

    let cursor;

    //查找游标，如果有就继续，没有则从零开始
    if (current_cursor.path == path) {
        cursor = {
            path,
            step: current_cursor.step,
            npkHeader: current_cursor.npkHeader,
            npkIndexs: current_cursor.npkIndexs,
            imgHeaders: current_cursor.imgHeaders,
            imgIndexs: current_cursor.imgIndexs,
            imgPngs: [],  //{path,index,png}
            errors: [],
        }

    } else {

        if (!fileIsExist(path)) {
            console.error(`读取NPK失败,未找到文件:${path}`);
            return new Promise((res, rej) => {
                rej(`读取NPK失败,未找到文件:${path}`)
            })
        }

        cursor = {
            path,
            step: LOAD_STEP.START,
            npkHeader: null,  //count对应npkIndexs.length
            npkIndexs: [],
            imgHeaders: [], //count对应imgIndexs.length  注意数组索引顺序
            imgIndexs: [],  //无序数组，用的时候根据index_name和index取
            imgPngs: [],  //{path,index,png}
            errors: [],
        }
    }

    return new Promise((res, rej) => {

        const next = (cursor) => {
            openNpk(cursor, step)
                .then(result => {
                    if (step >= result.step + 1) {
                        result.step++;
                        return next(result); //继续下一阶段
                    }

                    if (step < result.step + 1) {
                        // console.log("openNpkProxy 已完成任务")

                        //更新游标
                        Object.keys(current_cursor).forEach(key => {
                            current_cursor[key] = cursor[key];
                        })
                        return res(cursor); //完成，返回
                    }
                })
                .catch(e => {
                    rej(e);
                })
        }

        next(cursor);
    })
}

/*继续一个cursor */
const openCursor = (cursor, step) => {
    return new Promise((res, rej) => {

        const next = (cursor) => {
            openNpk(cursor, step)
                .then(result => {
                    if (step >= result.step + 1) {
                        result.step++;
                        return next(result); //继续下一阶段
                    }

                    if (step < result.step + 1) {
                        console.log("openCursor 已完成任务")
                        return res(cursor); //完成，返回
                    }
                })
                .catch(e => {
                    rej(e);
                })
        }

        next(cursor);
    })
}


module.exports = {
    openNpk: openNpkProxy,
    continueNpk: openCursor,
    LOAD_STEP,
}